package com.quick.develop.flowable.service.process;

import com.quick.develop.flowable.domain.BpmBaseDO;
import com.quick.develop.flowable.domain.vo.instance.BpmProcessInstanceCreateReqVO;
import com.quick.develop.framework.common.page.PageResult;
import com.quick.develop.framework.utils.collection.CollectionUtils;
import com.quick.develop.flowable.domain.instance.BpmProcessInstanceMyPageReqVO;
import com.quick.develop.flowable.domain.instance.BpmProcessInstancePageItemRespVO;
import com.quick.develop.flowable.domain.instance.BpmProcessInstanceRespVO;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author junyuan.liu
 * @description:  流程实例 Service 接口
 * @date 2022/4/22 10:37
 */
public interface IBpmProcessInstanceService {

    /** 
     * @description 获取流程实例 可以查个人和管理员所有的
     * @param pageReqVO 参数
     * @return com.quick.develop.framework.domain.PageResult<com.quick.develop.flowable.domain.instance.BpmProcessInstancePageItemRespVO>
     * @author junyuan.liu
     * @date 2022/9/13 14:53
     */ 
    PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(BpmProcessInstanceMyPageReqVO pageReqVO);
    
    /** 
     * @description 
     * @return long
     * @author junyuan.liu
     * @date 2022/11/3 13:12
     */ 
    long getMyProcessCount();

    /**
     * @description  获得单个流程实例
     * @param processInstanceId 流程实例的编号
     * @return org.flowable.engine.runtime.ProcessInstance
     * @author junyuan.liu
     * @date 2022/4/22 10:38
     */ 
    ProcessInstance getProcessInstance(String processInstanceId);

    /*** 
     * @description 获得流程实例集合
     * @param ids 流程实例的编号集合
     * @return java.util.List<org.flowable.engine.runtime.ProcessInstance>
     * @author junyuan.liu
     * @date 2022/4/22 10:38
     */ 
    List<ProcessInstance> getProcessInstanceList(Set<String> ids);

    /*** 
     * @description 获得流程实例 Map
     * @param ids 流程实例的编号集合
     * @return java.util.Map<java.lang.String,org.flowable.engine.runtime.ProcessInstance>
     * @author junyuan.liu
     * @date 2022/4/22 10:39
     */ 
    default Map<String, ProcessInstance> getProcessInstanceMap(Set<String> ids) {
        return CollectionUtils.convertMap(getProcessInstanceList(ids), ProcessInstance::getProcessInstanceId);
    }

    /** 
     * @description  获取历史流程实例
     * @param id 流程实例ID
     * @return org.flowable.engine.history.HistoricProcessInstance
     * @author junyuan.liu
     * @date 2022/6/20 18:47
     */ 
    HistoricProcessInstance getHistoricProcessInstance(String id);

    /*** 
     * @description  获得历史的流程实例列表
     * @param ids 流程实例的编号集合
     * @return  历史的流程实例列表
     * @author junyuan.liu
     * @date 2022/4/28 15:14
     */ 
    List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids);

    /*** 
     * @description  获得历史的流程实例 Map
     * @param ids 流程实例的编号集合
     * @return 历史的流程实例列表 Map
     * @author junyuan.liu
     * @date 2022/4/28 15:16
     */ 
    default Map<String, HistoricProcessInstance> getHistoricProcessInstanceMap(Set<String> ids) {
        return CollectionUtils.convertMap(getHistoricProcessInstances(ids), HistoricProcessInstance::getId);
    }


    /** 
     * @description  创建流程实例（提供给前端）
     * @param createReqVO 创建信息
     * @return 
     * @author junyuan.liu
     * @date 2022/4/26 19:07
     */ 
    String createProcessInstanceById(@Valid BpmProcessInstanceCreateReqVO createReqVO);

    /*** 
     * @description  创建流程实例（提供给前端）
     * @param createReqVO
     * @return 
     * @author junyuan.liu
     * @date 2022/4/29 9:31
     */ 
    String createProcessInstanceByKey(@Valid BpmProcessInstanceCreateReqVO createReqVO);

    /***
     * @description  通过流程实例ID获取流程图
     * @param httpServletResponse
     * @param processInstanceId
     * @return
     * @author junyuan.liu
     * @date 2022/4/27 15:45
     */
    void diagramViewByProInstId(HttpServletResponse httpServletResponse, String processInstanceId) throws Exception;

    /***
     * @description  判断流程是否结束
     * @param processInstanceId 流程实例ID
     * @return
     * @author junyuan.liu
     * @date 2022/4/27 16:20
     */
    boolean isProcessFinished(String processInstanceId);

    /** 
     * @description  获得流程实例 VO 信息
     * @param id 流程实例ID
     * @return com.quick.develop.flowable.domain.instance.BpmProcessInstanceRespVO
     * @author junyuan.liu
     * @date 2022/5/2 16:16
     */ 
    BpmProcessInstanceRespVO getProcessInstanceVO(String id);
    
    /** 
     * @description 获取流程启动者
     * @param processInstanceId 流程实例ID
     * @return java.lang.String
     * @author junyuan.liu
     * @date 2022/7/30 16:38
     */ 
    String getProcessStartUser(String processInstanceId);

    /**
     * @description 通过BusinessKey获取到流程实例
     * @param businessKey 业务KEY
     * @return java.util.List<org.flowable.engine.runtime.ProcessInstance>
     * @author junyuan.liu
     * @date 2022/5/12 13:16
     */
    List<ProcessInstance> getProcessInstanceByBusinessKey(String businessKey);
    
    /** 
     * @description 通过BusinessKey获取到流程实例
     * @param businessKey 业务key
     * @return java.util.List<org.flowable.engine.history.HistoricProcessInstance>
     * @author junyuan.liu
     * @date 2022/8/12 10:45
     */ 
    List<HistoricProcessInstance> getHisProcessInstancesByBusinessKey(String businessKey);
    
    /**
     * @description 通过 businessKey 获取主流程实例
     * @param businessKey 业务ID
     * @return org.flowable.engine.history.HistoricProcessInstance
     * @author junyuan.liu
     * @date 2022/8/11 11:21
     */ 
    HistoricProcessInstance getMainProcessInstanceByBusinessKey(String businessKey);

    /** 
     * @description 通过 ProcessInstanceId 获取主流程实例
     * @param id ProcessInstanceId
     * @return org.flowable.engine.history.HistoricProcessInstance
     * @author junyuan.liu
     * @date 2022/11/10 12:30
     */ 
    HistoricProcessInstance getMainProcessInstanceByProcessInstanceId(String id);
    
    /** 
     * @description 获取流程实例
     * @param businessKey 业务ID
     * @return java.util.List<com.quick.develop.flowable.domain.instance.BpmProcessInstanceRespVO>
     * @author junyuan.liu
     * @date 2022/8/15 9:46
     */ 
    List<BpmProcessInstanceRespVO> getProcessInstancesByBusinessKey(String businessKey);
    
    /** 
     * @description 查询是否有父流程
     * @param reqVo 请求 包含
     * @return java.util.List<com.quick.develop.flowable.domain.instance.BpmProcessInstanceRespVO>
     * @author junyuan.liu
     * @date 2022/8/15 13:48
     */ 
    List<BpmProcessInstanceRespVO> findParentProcesses(BpmBaseDO reqVo);
    
    /** 
     * @description 获取流程实例 包含父流程信息
     * @param reqVo 请求
     * @return java.util.List<com.quick.develop.flowable.domain.instance.BpmProcessInstanceRespVO>
     * @author junyuan.liu
     * @date 2022/8/15 17:54
     */ 
    List<BpmProcessInstanceRespVO> getProcessesIncludeSuper(BpmBaseDO reqVo);
    
    /** 
     * @description  更新流程启动者 包括历史数据
     * @param userId 发起人
     * @param processInstanceId 流程实例ID
     * @author junyuan.liu
     * @date 2022/6/1 9:35
     */ 
    void updateProcessStartUser(String userId, String processInstanceId);
    
    /** 
     * @description  更新历史流程实例业务ID
     * @param businessKey 业务ID
     * @param procInstId 流程实例ID
     * @author junyuan.liu
     * @date 2022/6/1 15:10
     */
    void updateHiProcessBusinessKey(String businessKey, String procInstId);


    void updateProcessNameByInstancesId(String processInstancesId, String newProcessName);

    /**
     * @Description: 获取业务查询的流程信息
     * @Param: [businessKeys]
     * @return: java.util.List<com.quick.develop.flowable.domain.instance.BpmProcessInstancePageItemRespVO>
     * @Author HJF
     * @Date 2023/7/19 15:42
     */
    List<BpmProcessInstancePageItemRespVO> getDocProcessData(List<String> businessKeys);
}
